Module Breakdown
Each module lives under
src/modules/<module>
, with its own Controllers, Services, and Repositories.
4.1 Authentication
- Controllers:
AuthController
(/auth/signup
,/auth/login
,/auth/token
) exposes sign-up, login, and token endpoints. - Service:
FirebaseAuthService
wraps Firebase Admin SDK for user creation, JWT issuance, and token verification. - Repository: Minimal, since Firebase is the source of truth; local DB used for profile data only.
Why? Offloads heavy lifting to Firebase—leveraging its scalability, secure token management, and built-in user lifecycle.
4.2 Courses
- Controllers:
CourseController
endpoints (/courses
,/courses/:id/versions
, etc.) - Service:
CourseService
implements versioning logic, content locking, and draft/publish workflows. - Repository:
CourseRepository
defines schemas forCourse
,Version
,Module
,Section
, andItem
subdocuments.
Why? Versioning courses independently supports safe iteration and rollbacks; keeping content hierarchies in subdocuments optimizes read performance.
4.3 Quizzes
- Controllers:
QuizController
for managing quizzes and attempts. - Service:
QuizService
uses a factory pattern to handle different question types (SOL, SML, OTL, NAT, DES). - Repository:
QuizRepository
,QuestionBankRepository
, andAttemptRepository
separate concerns for question storage vs. attempt tracking.
Why? Quiz logic is inherently complex—isolating types and attempts into dedicated repos and services maintains clarity and testability.
4.4 Users
- Controllers:
UserController
(/users/:id/enroll
,/users/:id/progress
) - Service:
EnrollmentService
andProgressService
track course enrollments and watch-time. - Repository:
UserRepository
with methods for progress snapshots, watch-time aggregates, and profile updates.
Why? Separating enrollment from progress allows flexible business rules (e.g., free vs. paid courses, quiz retakes).
4.5 Notifications
- Controllers:
NotificationController
(/notifications/invite
,/notifications/status
) - Service:
MailService
(SMTP) andInviteService
manage email invites and status tracking. - Repository:
InviteRepository
stores invite tokens, expiration, and status.
Why? Decoupling email transport from invite logic simplifies swapping providers or adding in-app notification channels later.
4.6 Settings
- Controllers:
SettingsController
(/settings/proctoring
,/settings/custom
) - Service:
SettingsService
reads/writes course- and user-level settings. - Repository:
SettingsRepository
with JSON-schema–validated storage.
Why? Proctoring and custom flags vary by course; having a dedicated module keeps these concerns isolated.
4.7 Anomalies
- Controllers:
AnomalyController
(/anomalies
,/anomalies/:id
) - Service:
AnomalyService
subscribes to watch-time events and applies threshold rules. - Repository:
AnomalyRepository
stores anomaly records with metadata (userId, courseId, timestamp).
Why? Early detection of suspicious behavior protects academic integrity and platform health.
4.8 GenAI
- Controllers:
GenAIController
(/genai/questions
,/genai/summaries
) - Service:
GenAIService
wraps OpenAI (or Ollama) clients, handles prompt templates and rate limits. - Repository: Optionally caches generated content in
GenAIRepository
to avoid redundant API calls.
Why? Centralizing prompt engineering and caching improves consistency, costs control, and performance.